package stringhelper

import (
	"crypto/md5"
	"encoding/base64"
	"encoding/hex"
	"errors"
	"log"
	"math"
	"strconv"
	"strings"
)

/**
 * StrStr 实现php中的strstr，needle是否是haystack的子串，为空则返回空字符串和false
 * 如果beforeNeedle是true, result返回子串位置之前，否则返回子串位置之后
 */
func StrStr(haystack, needle string, beforeNeedle bool) (result string, exist bool) {
	index := strings.Index(haystack, needle)
	if index == -1 {
		return
	}
	if beforeNeedle {
		return string([]rune(haystack)[:index]), true
	} else {
		return string([]rune(haystack)[index:]), true
	}
}

// StrContains 判断字符串数组中，是否包含某一字符串
func StrContains(s []string, e string) bool {
	for _, a := range s {
		if a == e {
			return true
		}
	}
	return false
}

// IsNum 实现类似php的is_number
func IsNum(s string) bool {
	_, err := strconv.ParseFloat(s, 64)
	return err == nil
}

// IsEmpty 判断字符串是否为空,为空则返回默认值
func IsEmpty(str string, defval string) (result string) {
	if str == "" {
		result = defval
	} else {
		result = str
	}
	return
}

// MD5Encode 进行MD5处理
// Deprecated: 被废弃，请使用新方法cryptohelper.MD5Encrypt
func MD5Encode(s string) string {
	h := md5.New()
	h.Write([]byte(s))
	return hex.EncodeToString(h.Sum(nil))
}

func Base64Encode(text string) (encoded string) {
	encoded = base64.StdEncoding.EncodeToString([]byte(text))
	return
}

func Base64Decode(text string) (decoded string, err error) {
	val, err := base64.StdEncoding.DecodeString(text)
	if err != nil {
		log.Println("Base64Decode err, ", err)
		return
	}
	decoded = string(val)
	return
}

func StringSplit(text string, step int) (arr []string) {
	r := []rune(text)
	strLen := len(r)
	if strLen <= 0 || step <= 0 || step > strLen {
		arr = append(arr, text)
		return
	}
	var page int = 1
	var pageCount = int(math.Ceil(float64(strLen) / float64(step)))
	for {
		start := (page - 1) * step
		end := start + step
		page++
		arr = append(arr, string(r[start:end]))
		if page > pageCount {
			break
		}
	}
	return
}

func SubStr(text string, start, end int) (result string, err error) {
	r := []rune(text)
	if start > end {
		err = errors.New("start and end range invalid")
		return
	}
	result = string(r[start:end])
	return
}

func Addslashes(str string) string {
	tmpRune := []rune{}
	for _, ch := range str {
		switch ch {
		case []rune{'\\'}[0], []rune{'"'}[0], []rune{'\''}[0]:
			tmpRune = append(tmpRune, []rune{'\\'}[0])
			tmpRune = append(tmpRune, ch)
		default:
			tmpRune = append(tmpRune, ch)
		}
	}
	return string(tmpRune)
}

func Stripslashes(str string) string {
	dstRune := []rune{}
	strRune := []rune(str)
	strLenth := len(strRune)
	for i := 0; i < strLenth; i++ {
		if strRune[i] == []rune{'\\'}[0] {
			i++
		}
		dstRune = append(dstRune, strRune[i])
	}
	return string(dstRune)
}
